JBoss Community Archive (Read Only)

WildFly 9

The HTTP management API

Introduction

The Management API in WildFly is accessible through multiple channels, one of them being HTTP and JSON.

Even if you haven't used a curl command line you light already have used this channel since it is how the web console interact with the Management API.

WildFly 9 is distributed secured by default, the default security mechanism is username / password based making use of HTTP Digest for the authentication process.

Thus you need to create a user with the add-user.sh script.

Interacting with the model

Since we must be authenticated , the client will have to support HTTP Digest authentication.

For example this can be activated in curl using the --digest option.

The WildFly HTTP Management API adheres to the REST principles so the GET operations must be idempotent.

This means that using a request with method GET can be used to read the model but you won't be able to change it.

You must use POST to change the model or read it. A POST request may contain the operation either in DMR or in JSON format as its body.

You have to define the Content-Type=application/json header in the request to specify that you are using some JSON.

If you want to submit DMR in the request body then the Content-Type or the Accept header should be "application/dmr-encoded".

GET for Reading

While you can do everything with POST, some operations can be called through a 'classical' GET request.

These are the supported operations for a GET :

  • attribute : for a read-attribute operation

  • resource : for a read-resource operation

  • resource-description : for a read-resource-description operation

  • snapshots : for the list-snapshots operation

  • operation-description : for a read-operation-description operation

  • operation-names : for ad read-operation-names operation

The URL format is the following one : http://server:9990/management/<path_to_resource>?operation=<operation_name>&operation_parameter=<value>...

path_to_resource is the path to the wanted resource replacing all '=' with '/' : thus for example subsystem=undertow/server=default-server becomes subsystem/undertow/server/default-server.

So to read the server-state :

http://localhost:9990/management?operation=attribute&name=server-state&json.pretty=1

Let's read some resource

  • This is simple operation that is equivalent of running :read-attribute(name=server-state) with CLI in root directory

    • Using GET

      http://localhost:9990/management?operation=attribute&name=server-state&json.pretty=1
    • Using POST

      $ curl --digest -L -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-attribute","name":"server-state","json.pretty":1}' -u admin
      Enter host password for user 'admin':
      HTTP/1.1 401 Unauthorized
      Connection: keep-alive
      WWW-Authenticate: Digest realm="ManagementRealm",domain="/management",nonce="P80WU3BANtQNMTQwNjg5Mzc5MDQ2MlpjmRaZ+Vlp1OVeNEGBeXg=",opaque="00000000000000000000000000000000",algorithm=MD5
      Content-Length: 77
      Content-Type: text/html
      Date: Fri, 01 Aug 2014 11:49:50 GMT
      
      HTTP/1.1 200 OK
      Connection: keep-alive
      Authentication-Info: nextnonce="M+h9aADejeINMTQwNjg5Mzc5MDQ2OPQbHKdAS8pRE8BbGEDY5uI="
      Content-Type: application/json; charset=utf-8
      Content-Length: 55
      Date: Fri, 01 Aug 2014 11:49:50 GMT
      
      {
          "outcome" : "success",
          "result" : "running"
      }
  • Here's an example of an operation on a resource with a nested address and passed parameters. This is same as if you would run /host=master/server=server-01:read-attribute(name=server-state)

$ curl --digest -L -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-attribute","address":[{"host":"master"},{"server":"server-01"}],"name":"server-state","json.pretty":1}'
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: application/json
Date: Tue, 17 Apr 2012 04:02:24 GMT

{
    "outcome" : "success",
    "result" : "running"
}
  • Following example will get us information from http connection in undertow subsystem including run-time attributes
    This is the same as running /subsystem=undertow/server=default-server:read-resource(include-runtime=true,recursive=true) in CLI

    • Using GET

      http://localhost:9990/management/subsystem/undertow/server/default-server?operation=resource&recursive=true&json.pretty=1
      
      {
          "default-host" : "default-host",
          "servlet-container" : "default",
          "ajp-listener" : null,
          "host" : {"default-host" : {
              "alias" : ["localhost"],
              "default-web-module" : "ROOT.war",
              "filter-ref" : {
                  "server-header" : {"predicate" : null},
                  "x-powered-by-header" : {"predicate" : null}
              },
              "location" : {"/" : {
                  "handler" : "welcome-content",
                  "filter-ref" : null
              }},
              "setting" : null
          }},
          "http-listener" : {"default" : {
              "allow-encoded-slash" : false,
              "allow-equals-in-cookie-value" : false,
              "always-set-keep-alive" : true,
              "buffer-pipelined-data" : true,
              "buffer-pool" : "default",
              "certificate-forwarding" : false,
              "decode-url" : true,
              "enabled" : true,
              "max-buffered-request-size" : 16384,
              "max-cookies" : 200,
              "max-header-size" : 51200,
              "max-headers" : 200,
              "max-parameters" : 1000,
              "max-post-size" : 10485760,
              "proxy-address-forwarding" : false,
              "read-timeout" : null,
              "receive-buffer" : null,
              "record-request-start-time" : false,
              "redirect-socket" : "https",
              "send-buffer" : null,
              "socket-binding" : "http",
              "tcp-backlog" : null,
              "tcp-keep-alive" : null,
              "url-charset" : "UTF-8",
              "worker" : "default",
              "write-timeout" : null
          }},
          "https-listener" : null
      }
    • Using POST

      $ curl --digest -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-resource", "include-runtime":"true" , "recursive":"true", "address":["subsystem","undertow","server","defult-server"], "json.pretty":1}' -u admin:admin
      HTTP/1.1 401 Unauthorized
      Connection: keep-alive
      WWW-Authenticate: Digest realm="ManagementRealm",domain="/management",nonce="a3paQ9E0/l8NMTQwNjg5OTU0NDk4OKjmim2lopZNc5zCevjYWpk=",opaque="00000000000000000000000000000000",algorithm=MD5
      Content-Length: 77
      Content-Type: text/html
      Date: Fri, 01 Aug 2014 13:25:44 GMT
      
      HTTP/1.1 200 OK
      Connection: keep-alive
      Authentication-Info: nextnonce="nTOSJd3ufO4NMTQwNjg5OTU0NDk5MeUsRw5rKXUT4Qvk1nbrG5c="
      Content-Type: application/json; charset=utf-8
      Content-Length: 1729
      Date: Fri, 01 Aug 2014 13:25:45 GMT
      
      {
          "outcome" : "success",
          "result" : {
              "default-host" : "default-host",
              "servlet-container" : "default",
              "ajp-listener" : null,
              "host" : {"default-host" : {
                  "alias" : ["localhost"],
                  "default-web-module" : "ROOT.war",
                  "filter-ref" : {
                      "server-header" : {"predicate" : null},
                      "x-powered-by-header" : {"predicate" : null}
                  },
                  "location" : {"/" : {
                      "handler" : "welcome-content",
                      "filter-ref" : null
                  }},
                  "setting" : null
              }},
              "http-listener" : {"default" : {
                  "allow-encoded-slash" : false,
                  "allow-equals-in-cookie-value" : false,
                  "always-set-keep-alive" : true,
                  "buffer-pipelined-data" : true,
                  "buffer-pool" : "default",
                  "certificate-forwarding" : false,
                  "decode-url" : true,
                  "enabled" : true,
                  "max-buffered-request-size" : 16384,
                  "max-cookies" : 200,
                  "max-header-size" : 51200,
                  "max-headers" : 200,
                  "max-parameters" : 1000,
                  "max-post-size" : 10485760,
                  "proxy-address-forwarding" : false,
                  "read-timeout" : null,
                  "receive-buffer" : null,
                  "record-request-start-time" : false,
                  "redirect-socket" : "https",
                  "send-buffer" : null,
                  "socket-binding" : "http",
                  "tcp-backlog" : null,
                  "tcp-keep-alive" : null,
                  "url-charset" : "UTF-8",
                  "worker" : "default",
                  "write-timeout" : null
              }},
              "https-listener" : null
          }
      }
  • You may also used some encoded DMR but the result won't be human readable

    curl --digest -u admin:admin --header "Content-Type: application/dmr-encoded" -d bwAAAAMACW9wZXJhdGlvbnMADXJlYWQtcmVzb3VyY2UAB2FkZHJlc3NsAAAAAAAHcmVjdXJzZVoB  http://localhost:9990/management
  • You can deploy applications on the server

    • First upload the file which will create a managed content. You will have to use http://localhost:9990/management/*add-content*

      curl --digest -u admin:admin --form file=@tiny-webapp.war  http://localhost:9990/management/add-content
      {"outcome" : "success", "result" : { "BYTES_VALUE" : "+QJlHTDrogO9pm/57GkT/vxWNz0=" }}
    • Now let's deploy the application

      curl --digest -u admin:admin -L --header "Content-Type: application/json" -d '{"content":[{"hash": {"BYTES_VALUE" : "+QJlHTDrogO9pm/57GkT/vxWNz0="}}], "address": [{"deployment":"tiny-webapp.war"}], "operation":"add", "enabled":"true"}' http://localhost:9990/management
      {"outcome" : "success"}

      Using some JAX-RS code

HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest("admin", "admin");
Client client = ClientBuilder.newClient();
client.register(feature);
Entity<SimpleOperation> operation = Entity.entity(
    new SimpleOperation("read-resource", true, "subsystem", "undertow", "server", "default-server"), 
    MediaType.APPLICATION_JSON_TYPE);
WebTarget managementResource = client.target("http://localhost:9990/management");
String response = managementResource.request(MediaType.APPLICATION_JSON_TYPE)
    .header("Content-type", MediaType.APPLICATION_JSON)
    .post(operation, String.class);
System.out.println(response);


{"outcome" : "success", "result" : {"default-host" : "default-host", "servlet-container" : "default", "ajp-listener" : null, "host" : {"default-host" : {"alias" : ["localhost"], "default-web-module" : "ROOT.war", "filter-ref" : {"server-header" : {"predicate" : null}, "x-powered-by-header" : {"predicate" : null}}, "location" : {"/" : {"handler" : "welcome-content", "filter-ref" : null}}, "setting" : null}}, "http-listener" : {"default" : {"allow-encoded-slash" : false, "allow-equals-in-cookie-value" : false, "always-set-keep-alive" : true, "buffer-pipelined-data" : true, "buffer-pool" : "default", "certificate-forwarding" : false, "decode-url" : true, "enabled" : true, "max-buffered-request-size" : 16384, "max-cookies" : 200, "max-header-size" : 51200, "max-headers" : 200, "max-parameters" : 1000, "max-post-size" : 10485760, "proxy-address-forwarding" : false, "read-timeout" : null, "receive-buffer" : null, "record-request-start-time" : false, "redirect-socket" : "https", "send-buffer" : null, "socket-binding" : "http", "tcp-backlog" : null, "tcp-keep-alive" : null, "url-charset" : "UTF-8", "worker" : "default", "write-timeout" : null}}, "https-listener" : null}}
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:54:09 UTC, last content change 2014-08-01 16:13:24 UTC.